package com.credithc.signature.manager.service.syncsign;

import com.credithc.signature.common.constant.CoreConstant;
import com.credithc.signature.common.constant.SealConstant;
import com.credithc.signature.common.ro.core.CoreRequet;
import com.credithc.signature.common.ro.facade.RequestData;
import com.credithc.signature.common.ro.facade.RestSignatureReq;
import com.credithc.signature.common.service.SignatureLogService;
import com.credithc.signature.common.utils.MessageFilterUtil;
import com.credithc.signature.manager.utils.FileUploadUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述：同步签章调用<br/>
 * 作者：sunyang
 * 创建：2019/7/1 14:47
 * 版本：v1.0.0<br/>
 */
@Slf4j
@Service
public class SignSyncService {

    @Autowired
    private GeneratePDFServiceSync generatePDFServiceSync;

    @Autowired
    private SignatureServiceSync signatureServiceSync;

    @Autowired
    private SignatureLogService signatureLogService;

    /**
     * 转发签章请求到core
     *
     * @param restSignatureReq
     * @param signatureSN
     * @return
     */
    public String signature(RestSignatureReq restSignatureReq, String signatureSN) {
        try {
            final CoreRequet coreRequet = new CoreRequet();
            coreRequet.setRequestSn(signatureSN);
            coreRequet.setTemplateNo(restSignatureReq.getTemplateNo());
            coreRequet.setChannelNo(restSignatureReq.getChannelNo());
            coreRequet.setNeedSign(restSignatureReq.getNeedSign());
            coreRequet.setCallbackUrl(restSignatureReq.getCallBackUrl());

            // 1.序列化消息
            List<Map<String, Object>> certInfos = new ArrayList<>();
            Map<String, List<Map<String, String>>> listData = new HashMap<>(16);
            Map<String, String> otherData = new HashMap<>(16);
            List<String> sealCodes = null;
            sealCodes = decodeJsonBody(restSignatureReq.getRequestData(), certInfos, listData, otherData, sealCodes);

            // 2.生成PDF
            String pdfPath = null;
            try {
                log.info("手动签章请求数据......certInfos:{},listData:{},otherData:{}", certInfos, listData, otherData);
                pdfPath = generatePDFServiceSync.generatePDF(coreRequet, listData, otherData);
            } catch (Exception e) {
                String errorMsg = MessageFilterUtil.limitLength(e.getMessage());
                signatureLogService.updateResult(errorMsg, signatureSN);
                log.error("－消息－:requestSn={},生成pdf失败", coreRequet.getRequestSn());
                throw new RuntimeException(e);
            }

            // 3.签章
            if (coreRequet.getNeedSign()) {
                try {
                    // 签章逻辑
                    pdfPath = signatureServiceSync.signature(coreRequet, pdfPath, certInfos, sealCodes);
                } catch (Exception e) {
                    log.error("－消息－:requestSn={},签章失败", coreRequet.getRequestSn());
                    throw new RuntimeException(e);
                }
            }
            //4.上传到文件系统
            String signPdfName = CoreConstant.SNAP_PDF_PREFIX + coreRequet.getRequestSn() + CoreConstant.PDF_EXT;
            return FileUploadUtil.uploadAndGetUrl(pdfPath, SealConstant.DOC, signPdfName, coreRequet.getRequestSn());
        } catch (Throwable e) {
            log.error("手动执行签章发生异常......", e);
            return "手动执行签章失败";
            //ResponseUtil.getResponseMessage(ResponseEnum.FAIL.getCode());
        }
    }

    /**
     * 解包jsonBody
     *
     * @param jsonBody
     * @param certInfos
     * @param listData
     * @param otherData
     */
    private List<String> decodeJsonBody(RequestData jsonBody, List<Map<String, Object>> certInfos, Map<String, List<Map<String, String>>> listData, Map<String, String> otherData, List<String> sealCodes) {
        boolean isNewSignature = isNewSignature(jsonBody);

        if (isNewSignature) {
            if(jsonBody.getCertInfos() != null){
                certInfos.addAll(jsonBody.getCertInfos());
            }
            if(jsonBody.getListData() != null){
                listData.putAll(jsonBody.getListData());
            }
            if(jsonBody.getOtherData() != null){
                otherData.putAll(jsonBody.getOtherData());
            }
            if (jsonBody.getOfficialSealsCodes() != null) {
                sealCodes = new ArrayList<>();
                sealCodes.addAll(jsonBody.getOfficialSealsCodes());
            }
        } else {
            if(jsonBody.getCertApplys() != null){
                certInfos.addAll(jsonBody.getCertApplys());
            }
            if(jsonBody.getListElements() != null){
                listData.putAll(jsonBody.getListElements());
            }
            if(jsonBody.getSingnalElement() != null){
                otherData.putAll(jsonBody.getSingnalElement());
            }
            if (jsonBody.getOfficialSealsCodes() != null) {
                sealCodes = jsonBody.getOfficialSealsCodes();
            }
        }
        return sealCodes;
    }

    /**
     * 判断是否是新签章请求参数
     *
     * @param jsonBody
     * @return
     */
    private boolean isNewSignature(RequestData jsonBody) {
        List certApplys = jsonBody.getCertApplys();
        Map<String, List<Map<String, String>>> listElements = jsonBody.getListElements();
        Map<String, String> singnalElement = jsonBody.getSingnalElement();
        if (certApplys == null && listElements == null && singnalElement == null) {
            return true;
        }
        return false;
    }
}
